Trò chơi Angry Birds trong UNITY Engine
31.678 lượt xem;
1 using UnityEngine;
2 using System.Collections.Generic;
3 using Assets.Scripts;
4 using System.Linq;
5
6 public class GameManager : MonoBehaviour
7 {
8
9 public CameraFollow cameraFollow;
10 int currentBirdIndex;
11 public SlingShot slingshot;
12 [HideInInspector]
13 public static GameState CurrentGameState = GameState.Start;
14 private List<GameObject> Bricks;
15 private List<GameObject> Birds;
16 private List<GameObject> Pigs;
17
18 // Use this for initialization
19 void Start()
20 {
21 CurrentGameState = GameState.Start;
22 slingshot.enabled = false;
23 //find all relevant game objects
24 Bricks = new List<GameObject>(GameObject.FindGameObjectsWithTag("Brick"));
25 Birds = new List<GameObject>(GameObject.FindGameObjectsWithTag("Bird"));
26 Pigs = new List<GameObject>(GameObject.FindGameObjectsWithTag("Pig"));
27 //unsubscribe and resubscribe from the event
28 //this ensures that we subscribe only once
29 slingshot.BirdThrown -= Slingshot_BirdThrown; slingshot.BirdThrown += Slingshot_BirdThrown;
30 }
31
32
33 // Update is called once per frame
34 void Update()
35 {
36 switch (CurrentGameState)
37 {
38 case GameState.Start:
39 //if player taps, begin animating the bird
40 //to the slingshot
41 if (Input.GetMouseButtonUp(0))
42 {
43 AnimateBirdToSlingshot();
44 }
45 break;
46 case GameState.BirdMovingToSlingshot:
47 //do nothing
48 break;
49 case GameState.Playing:
50 //if we have thrown a bird
51 //and either everything has stopped moving
52 //or there has been 5 seconds since we threw the bird
53 //animate the camera to the start position
54 if (slingshot.slingshotState == SlingshotState.BirdFlying &&
55 (BricksBirdsPigsStoppedMoving() || Time.time - slingshot.TimeSinceThrown > 5f))
56 {
57 slingshot.enabled = false;
58 AnimateCameraToStartPosition();
59 CurrentGameState = GameState.BirdMovingToSlingshot;
60 }
61 break;
62 //if we have won or lost, we will restart the level
63 //in a normal game, we would show the "Won" screen
64 //and on tap the user would go to the next level
65 case GameState.Won:
66 case GameState.Lost:
67 if (Input.GetMouseButtonUp(0))
68 {
69 Application.LoadLevel(Application.loadedLevel);
70 }
71 break;
72 default:
73 break;
74 }
75 }
76
77
78 /// <summary>
79 /// A check whether all Pigs are null
80 /// i.e. they have been destroyed
81 /// </summary>
82 /// <returns></returns>
83 private bool AllPigsDestroyed()
84 {
85 return Pigs.All(x => x == null);
86 }
87
88 /// <summary>
89 /// Animates the camera to the original location
90 /// When it finishes, it checks if we have lost, won or we have other birds
91 /// available to throw
92 /// </summary>
93 private void AnimateCameraToStartPosition()
94 {
95 float duration = Vector2.Distance(Camera.main.transform.position, cameraFollow.StartingPosition) / 10f;
96 if (duration == 0.0f) duration = 0.1f;
97 //animate the camera to start
98 Camera.main.transform.positionTo
99 (duration,
100 cameraFollow.StartingPosition). //end position
101 setOnCompleteHandler((x) =>
102 {
103 cameraFollow.IsFollowing = false;
104 if (AllPigsDestroyed())
105 {
106 CurrentGameState = GameState.Won;
107 }
108 //animate the next bird, if available
109 else if (currentBirdIndex == Birds.Count - 1)
110 {
111 //no more birds, go to finished
112 CurrentGameState = GameState.Lost;
113 }
114 else
115 {
116 slingshot.slingshotState = SlingshotState.Idle;
117 //bird to throw is the next on the list
118 currentBirdIndex++;
119 AnimateBirdToSlingshot();
120 }
121 });
122 }
123
124 /// <summary>
125 /// Animates the bird from the waiting position to the slingshot
126 /// </summary>
127 void AnimateBirdToSlingshot()
128 {
129 CurrentGameState = GameState.BirdMovingToSlingshot;
130 Birds[currentBirdIndex].transform.positionTo
131 (Vector2.Distance(Birds[currentBirdIndex].transform.position / 10,
132 slingshot.BirdWaitPosition.transform.position) / 10, //duration
133 slingshot.BirdWaitPosition.transform.position). //final position
134 setOnCompleteHandler((x) =>
135 {
136 x.complete();
137 x.destroy(); //destroy the animation
138 CurrentGameState = GameState.Playing;
139 slingshot.enabled = true; //enable slingshot
140 //current bird is the current in the list
141 slingshot.BirdToThrow = Birds[currentBirdIndex];
142 });
143 }
144
145 /// <summary>
146 /// Event handler, when the bird is thrown, camera starts following it
147 /// </summary>
148 /// <param name="sender"></param>
149 /// <param name="e"></param>
150 private void Slingshot_BirdThrown(object sender, System.EventArgs e)
151 {
152 cameraFollow.BirdToFollow = Birds[currentBirdIndex].transform;
153 cameraFollow.IsFollowing = true;
154 }
155
156 /// <summary>
157 /// Check if all birds, pigs and bricks have stopped moving
158 /// </summary>
159 /// <returns></returns>
160 bool BricksBirdsPigsStoppedMoving()
161 {
162 foreach (var item in Bricks.Union(Birds).Union(Pigs))
163 {
164 if (item != null && item.GetComponent<Rigidbody2D>().velocity.sqrMagnitude > Constants.MinVelocity)
165 {
166 return false;
167 }
168 }
169
170 return true;
171 }
172
173 /// <summary>
174 /// Found here
175 /// http://www.bensilvis.com/?p=500
176 /// </summary>
177 /// <param name="screenWidth"></param>
178 /// <param name="screenHeight"></param>
179 public static void AutoResize(int screenWidth, int screenHeight)
180 {
181 Vector2 resizeRatio = new Vector2((float)Screen.width / screenWidth, (float)Screen.height / screenHeight);
182 GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(resizeRatio.x, resizeRatio.y, 1.0f));
183 }
184
185 /// <summary>
186 /// Shows relevant GUI depending on the current game state
187 /// </summary>
188 void OnGUI()
189 {
190 AutoResize(800, 480);
191 switch (CurrentGameState)
192 {
193 case GameState.Start:
194 GUI.Label(new Rect(0, 150, 200, 100), "Tap the screen to start");
195 break;
196 case GameState.Won:
197 GUI.Label(new Rect(0, 150, 200, 100), "You won! Tap the screen to restart");
198 break;
199 case GameState.Lost:
200 GUI.Label(new Rect(0, 150, 200, 100), "You lost! Tap the screen to restart");
201 break;
202 default:
203 break;
204 }
205 }
206
207
208 }
2 using System.Collections.Generic;
3 using Assets.Scripts;
4 using System.Linq;
5
6 public class GameManager : MonoBehaviour
7 {
8
9 public CameraFollow cameraFollow;
10 int currentBirdIndex;
11 public SlingShot slingshot;
12 [HideInInspector]
13 public static GameState CurrentGameState = GameState.Start;
14 private List<GameObject> Bricks;
15 private List<GameObject> Birds;
16 private List<GameObject> Pigs;
17
18 // Use this for initialization
19 void Start()
20 {
21 CurrentGameState = GameState.Start;
22 slingshot.enabled = false;
23 //find all relevant game objects
24 Bricks = new List<GameObject>(GameObject.FindGameObjectsWithTag("Brick"));
25 Birds = new List<GameObject>(GameObject.FindGameObjectsWithTag("Bird"));
26 Pigs = new List<GameObject>(GameObject.FindGameObjectsWithTag("Pig"));
27 //unsubscribe and resubscribe from the event
28 //this ensures that we subscribe only once
29 slingshot.BirdThrown -= Slingshot_BirdThrown; slingshot.BirdThrown += Slingshot_BirdThrown;
30 }
31
32
33 // Update is called once per frame
34 void Update()
35 {
36 switch (CurrentGameState)
37 {
38 case GameState.Start:
39 //if player taps, begin animating the bird
40 //to the slingshot
41 if (Input.GetMouseButtonUp(0))
42 {
43 AnimateBirdToSlingshot();
44 }
45 break;
46 case GameState.BirdMovingToSlingshot:
47 //do nothing
48 break;
49 case GameState.Playing:
50 //if we have thrown a bird
51 //and either everything has stopped moving
52 //or there has been 5 seconds since we threw the bird
53 //animate the camera to the start position
54 if (slingshot.slingshotState == SlingshotState.BirdFlying &&
55 (BricksBirdsPigsStoppedMoving() || Time.time - slingshot.TimeSinceThrown > 5f))
56 {
57 slingshot.enabled = false;
58 AnimateCameraToStartPosition();
59 CurrentGameState = GameState.BirdMovingToSlingshot;
60 }
61 break;
62 //if we have won or lost, we will restart the level
63 //in a normal game, we would show the "Won" screen
64 //and on tap the user would go to the next level
65 case GameState.Won:
66 case GameState.Lost:
67 if (Input.GetMouseButtonUp(0))
68 {
69 Application.LoadLevel(Application.loadedLevel);
70 }
71 break;
72 default:
73 break;
74 }
75 }
76
77
78 /// <summary>
79 /// A check whether all Pigs are null
80 /// i.e. they have been destroyed
81 /// </summary>
82 /// <returns></returns>
83 private bool AllPigsDestroyed()
84 {
85 return Pigs.All(x => x == null);
86 }
87
88 /// <summary>
89 /// Animates the camera to the original location
90 /// When it finishes, it checks if we have lost, won or we have other birds
91 /// available to throw
92 /// </summary>
93 private void AnimateCameraToStartPosition()
94 {
95 float duration = Vector2.Distance(Camera.main.transform.position, cameraFollow.StartingPosition) / 10f;
96 if (duration == 0.0f) duration = 0.1f;
97 //animate the camera to start
98 Camera.main.transform.positionTo
99 (duration,
100 cameraFollow.StartingPosition). //end position
101 setOnCompleteHandler((x) =>
102 {
103 cameraFollow.IsFollowing = false;
104 if (AllPigsDestroyed())
105 {
106 CurrentGameState = GameState.Won;
107 }
108 //animate the next bird, if available
109 else if (currentBirdIndex == Birds.Count - 1)
110 {
111 //no more birds, go to finished
112 CurrentGameState = GameState.Lost;
113 }
114 else
115 {
116 slingshot.slingshotState = SlingshotState.Idle;
117 //bird to throw is the next on the list
118 currentBirdIndex++;
119 AnimateBirdToSlingshot();
120 }
121 });
122 }
123
124 /// <summary>
125 /// Animates the bird from the waiting position to the slingshot
126 /// </summary>
127 void AnimateBirdToSlingshot()
128 {
129 CurrentGameState = GameState.BirdMovingToSlingshot;
130 Birds[currentBirdIndex].transform.positionTo
131 (Vector2.Distance(Birds[currentBirdIndex].transform.position / 10,
132 slingshot.BirdWaitPosition.transform.position) / 10, //duration
133 slingshot.BirdWaitPosition.transform.position). //final position
134 setOnCompleteHandler((x) =>
135 {
136 x.complete();
137 x.destroy(); //destroy the animation
138 CurrentGameState = GameState.Playing;
139 slingshot.enabled = true; //enable slingshot
140 //current bird is the current in the list
141 slingshot.BirdToThrow = Birds[currentBirdIndex];
142 });
143 }
144
145 /// <summary>
146 /// Event handler, when the bird is thrown, camera starts following it
147 /// </summary>
148 /// <param name="sender"></param>
149 /// <param name="e"></param>
150 private void Slingshot_BirdThrown(object sender, System.EventArgs e)
151 {
152 cameraFollow.BirdToFollow = Birds[currentBirdIndex].transform;
153 cameraFollow.IsFollowing = true;
154 }
155
156 /// <summary>
157 /// Check if all birds, pigs and bricks have stopped moving
158 /// </summary>
159 /// <returns></returns>
160 bool BricksBirdsPigsStoppedMoving()
161 {
162 foreach (var item in Bricks.Union(Birds).Union(Pigs))
163 {
164 if (item != null && item.GetComponent<Rigidbody2D>().velocity.sqrMagnitude > Constants.MinVelocity)
165 {
166 return false;
167 }
168 }
169
170 return true;
171 }
172
173 /// <summary>
174 /// Found here
175 /// http://www.bensilvis.com/?p=500
176 /// </summary>
177 /// <param name="screenWidth"></param>
178 /// <param name="screenHeight"></param>
179 public static void AutoResize(int screenWidth, int screenHeight)
180 {
181 Vector2 resizeRatio = new Vector2((float)Screen.width / screenWidth, (float)Screen.height / screenHeight);
182 GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(resizeRatio.x, resizeRatio.y, 1.0f));
183 }
184
185 /// <summary>
186 /// Shows relevant GUI depending on the current game state
187 /// </summary>
188 void OnGUI()
189 {
190 AutoResize(800, 480);
191 switch (CurrentGameState)
192 {
193 case GameState.Start:
194 GUI.Label(new Rect(0, 150, 200, 100), "Tap the screen to start");
195 break;
196 case GameState.Won:
197 GUI.Label(new Rect(0, 150, 200, 100), "You won! Tap the screen to restart");
198 break;
199 case GameState.Lost:
200 GUI.Label(new Rect(0, 150, 200, 100), "You lost! Tap the screen to restart");
201 break;
202 default:
203 break;
204 }
205 }
206
207
208 }